/**
 * 处理排单类
 */
class assignRoute
{
     static getInstance()
     {
         if(!assignRoute.instance)
         {
             assignRoute.instance = new assignRoute();
         }
         return assignRoute.instance;
     }
    render(){
          return new Promise( (resolve,reject)=>{
            let source=$('#route-list-template').html();
            let template = Handlebars.compile(source);
            $('#route-list').html(template({data:this.getRouters()}));
           // this.countDelayPoints();
            resolve('SUCCESS');
          })
    }

    /**
     * 获取每条路由
     * @returns {Array}
     */
    getRouters()
    {
        let data = [];
        let routers = OBJECT.directionsDisplay;
        let currentRouterId = CONFIG.currentOpearateRouterId;
        for( let key in routers ) {
            let t={};
            let distanceAndTime={};
            distanceAndTime = this.calcDistanceAndTimes(key)
            t.vehicleId = this.getVehicleName(key) || 'UnAssign';
            t.driver = this.getDriverName(key) || 'UnAssign';
            t.points = routers[key].routers;
            t.stops = routers[key].routers.length;
            t.name = OBJECT.routersNameMap[key];
            t.lbs = this.calcLbs(routers[key].routers);
            t.distance = distanceAndTime.distance;
            t.time     =distanceAndTime.time
            t.routerBg = OBJECT.routersBgColorMap[key];
            t.routerId = key;
            data.push(t);
            this.caleOverWorkTime( key, t.time);
            this.showRoutePoints(key,t.driver)
        }
        return data;
    }

    /**
     * 计算是否超过了工作时间，如果超出了工作时间把routerId 写进去每个Router异常信息变量（exceptionRouter）
     * @param routerId
     * @param time
     */
    caleOverWorkTime( routerId , time)
    {
        let driver = Driver.getInstance().getDriverByRouterId(routerId);
        if(driver)
        {
            let workTime = driver.work_hours || 0;
            if( workTime <= time)
            {
                OBJECT.exceptionRouter.add(routerId);
            }
        }
    }
    /**
     * 计算路线的总磅数
     * @param points
     * @returns {number}
     */
    calcLbs( points ) {
          let lbs = 0;
          points.forEach( function ( value ) {
               lbs = lbs+ value.GrossWeight;
          })
        return lbs.toFixed(2);
    }

    /**
     * 计算路线的距离和时间
     * @param routerId
     * @returns {{distance: string, time: string}}
     */
    calcDistanceAndTimes( routerId ){

        let schedule = OBJECT.routerPonits[routerId].schedule;
        let points = OBJECT.routerPonits[routerId].points;
        let distance = 0;
        let time = 0;
        schedule.forEach( function ( value,index ) {
             if( index >= 1)
             {
                 let d = value.distance.value / 1610 ;
                 let t = value.duration.value /60 / 60 ;
                 distance  = distance + Number(d);
                 time = time + Number(t);  //实际时间
                 time = time + (getMinuteFromStringDate(points[index-1].TimeOnSite) / 60);
             }
        })
        return {distance:distance.toFixed(2),time: time.toFixed(2) }
    }

    /**
     * 计算单条路线的超时的站点
     * @param data
     * @returns {number}
     */
    countDelayPointsOnRoute( data )
    {
        let count=0;
        for( let i=0;i<data.length;i++ )
        {
            if(data[i].delay)
            {
                count++;
            }
        }
       return count;
    }

    /**
     * 显示路线的站点详细信息
     * @param routerId
     */
    showRoutePoints( routerId ,driver) {

        let _this = this;
        let isHaveLunch = false;                 //司机是否吃了午餐
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        Router.getInstance().setCurrentRouterId( routerId );
        let departrueTime = this.getDriverDepartureTime( routerId );
        if( departrueTime == null )
        {
            return false;
        }
        let arr = OBJECT.routerPonits[routerId];
        let data=[];
        if(!arr.schedule){
            return false;
        }
        arr.points.forEach( function ( value ,index ) {

            let o ={};
            o.Address = value.Address;
            o.ScheduleID = value.ScheduleID || '--'
            o.ScheduleTime = value.ScheduleTime || '--';
            o.lbs    = value.GrossWeight;      //磅数
            o.CustomerTag = value.CustomerTag;
            let schedule = arr.schedule[index];
            let waitTime = getMinuteFromStringDate( value.TimeOnSite );
            let duration = schedule.duration.value / 60 ;
            duration = Math.ceil(duration) + Math.ceil(waitTime) ;
            o.distance = schedule.distance.text;
            o.minute = schedule.duration.text
            o.arriveTime = increaMinuteFromStringDate( departrueTime , duration);  //加上路程的时间和停留时间
            let driverId = OBJECT.routerPonits[routerId].driverId;
            let isLunchTime = this.isTimeForLunch(driverId,o.arriveTime );

            if( isLunchTime.result && isHaveLunch=== false)    //司机到了吃饭的时间
            {
                  isHaveLunch = true;
                  o.arriveTime = increaMinuteFromStringDate( o.arriveTime, isLunchTime.delayDelivery);
                  o.minute = o.minute;
                  data.push({                //把司机吃午饭加入schedule
                      exception:true,
                      duration:isLunchTime.delayDelivery
                  });
            }
            o.delay = false;
            if( !isBetweenStringTime( o.ScheduleTime , o.arriveTime) )
            {
                o.delay =  true;
            }
            departrueTime = o.arriveTime;
            data.push(o)
        },this)
        let source=$('#route-points-list-template').html();
        let template = Handlebars.compile(source);
        $('#route-points-list').html(template({data:data,driver:driver}));
        this.addListenerToTable();
    }

    /**
     * 计算司机是否到了吃饭时间
     *  如果司机到时间去吃饭，则返回延迟配送的分钟
     * @param driverId
     * @param time
     * @returns {{result: boolean, delayDelivery: number}}
     */
   isTimeForLunch( driverId, time)
   {
       let driver =Driver.getInstance().getDriverById( driverId );
       let departure_time = driver.departure_time;                   //获取司机出发时间
       let driver_work_hour = CONFIG.wareHouseCenter.driver_work_hour ;  //获取司机工作多久后去吃饭时间
       let lunchTime = increaMinuteFromStringDate(departure_time,driver_work_hour*60);   //计算司机应该去吃饭的时间
       let muchTimeForTime = getTimeDiff(lunchTime,time);                              //计算还有多久要去去午餐
       if( muchTimeForTime >30 )    //司机应该去吃饭
       {
              return {result:true,delayDelivery:driver_work_hour*60}
       }
       return {result:false,delayDelivery:0}

   }
    /**
     * 计算最优路线
     * @param data
     * @returns {*}
     */
    optimizeOrderpoints(data , routerId, driver ,countTime )
    {

        OBJECT.routerPonits[routerId].points.sort(function (a, b) {
            return SortByProps(a, b, { "arriveStartTimeString": "ascending", "arriveEndTimeString": "ascending" });
        });
         Router.getInstance().calculateRoute( OBJECT.routerPonits[routerId].points , routerId , OBJECT.routersBgColorMap[routerId] );
        this.showRoutePoints( routerId , driver ,2 );
    }
    /**
     * 统计迟到的数量
     */
    countDelayPoints()
    {
        CONFIG.delayPointsCounter=0;
        OBJECT.exceptionRouter = new Set()
        for(let routerId in OBJECT.routerPonits )
        {

            let weight =0;
            let departrueTime = this.getDriverDepartureTime( routerId );
            if(typeof OBJECT.routerPonits[routerId].points =='undefined')
            {
                continue;
            }
            if( departrueTime == null)
            {
               continue;
            }
            let arr = OBJECT.routerPonits[routerId];
            if(!arr.schedule){
                continue;
            }
            arr.points.forEach( function ( value ,index ) {

                    let count = false;
                    let o ={};
                    o.ScheduleTime = value.ScheduleTime || '--';
                    let schedule = arr.schedule[index];
                    let waitTime = getMinuteFromStringDate( value.TimeOnSite )
                    let duration = schedule.duration.value / 60 ;
                    duration = Math.ceil(duration) + Math.ceil(waitTime) ;
                    weight = weight + o.weight;
                    //计算是否在最大磅数和最小磅数范围
                    let maxAndminWeight = this.getMaxAndMinWeight(routerId);
                    if( weight < maxAndminWeight.min_weight || weight > maxAndminWeight )
                    {
                        OBJECT.exceptionRouter.add( routerId );
                    }
                    o.arriveTime = increaMinuteFromStringDate( departrueTime , duration);
                    if( !isBetweenStringTime( o.ScheduleTime , o.arriveTime) )
                    {
                       CONFIG.delayPointsCounter++;
                       OBJECT.exceptionRouter.add( routerId );
                    }
                    this.driverWaitOverOneHour(o.arriveTime,o.ScheduleTime,routerId);
                    departrueTime = o.arriveTime;

            },this)
        }
    }

    /**
     * 司机等待超过一个小时
     * @param arriveTime
     * @param ScheduleTime
     * @param routerId
     */
    driverWaitOverOneHour(arriveTime,ScheduleTime,routerId)
    {
         let shouldArrive = ScheduleTime.split('--')[0];
         if( getTimeDiff(arriveTime,shouldArrive) >10 )
         {
             OBJECT.driverWaitOverOneHour.add( routerId )
         }
    }

    /**
     * 获取司机的出发时间
     * @param routerId
     */
    getDriverDepartureTime(routerId)
    {
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let driverId = this.getDriverId(routerId);
        let departure_time;
        let drivers = OBJECT.driverList;
        if(!driverId)
        {
           return null;
        }
        drivers.forEach( function ( value ) {
               if( value.driver_id == driverId ) {
                   departure_time = value.departure_time;    //在foreach直接return 无效
               }
        })
        return departure_time;

    }
    /**
     * 获取车辆的最大磅数和最小磅数
     * @param routerId
     */
    getMaxAndMinWeight(routerId)
    {
        let ret ={}
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let vehicleId = OBJECT.routerPonits[routerId].vehicleId;
        if(!vehicleId)
        {
            return null;
        }

        OBJECT.vehicleList.forEach( function ( value ) {
            if( value.vehicle_id == vehicleId ) {
                ret = {max_weight:value.max_weight,min_weight:value.min_weight }
            }
        })
        return ret;

    }
    /**
     * 获取司机的名字
     * @param routerId
     */
    getDriverName(routerId)
    {
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let driverId = OBJECT.routerPonits[routerId].driverId;
        let nickname = null;
        let drivers =OBJECT.driverList;
        drivers.forEach( function ( value ) {
            if( value.driver_id == driverId ) {
                nickname = value.nickname;    //在foreach直接return 无效
            }
        })
        return nickname;

    }
    /**
     * 获取司机ID
     * @param routerId
     */
    getDriverId(routerId)
    {
        return OBJECT.routerPonits[routerId].driverId;
    }
    /**
     * 获取车辆的名字
     * @param routerId
     */
    getVehicleName(routerId)
    {
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let vehicleName = null;
        let vehicleId= OBJECT.routerPonits[routerId].vehicleId;
        let vehicle = OBJECT.vehicleList;
        vehicle.forEach( function ( value ) {
            if( value.vehicle_id == vehicleId ) {
                vehicleName = value.name;    //在foreach直接return 无效
            }
        })
        return vehicleName;

    }
    /**
     * 拖动顺序后重新排序站点顺序
     *
     * @returns {boolean}
     */
    reOrderRoutePoints () {
          let routerId = Router.getInstance().getCurrentRouterId();
          if(!routerId) {
              return false;
          }
          let orders = $('#route-points-list-body tr.route-points-info');
          let oldOrders = OBJECT.routerPonits[routerId].points;
          let newOrders=[];
          $.each( orders , function ( index , value ){
              let k = $(value).data('key');
              newOrders.push( oldOrders[k] );
          })
         OBJECT.routerPonits[routerId].points = newOrders;
         CONFIG.optimizeOrderpoints[routerId] = false
         Queue(routerId)

    }

    /**
     *给列表添加拖动监听事件
     */
    addListenerToTable (){
        let _this = this;
        let a = $("#table-sort").tableDnD({
            scrollAmount:10,
            onDragClass:'highlight',
            onDrop: function(table,row) {
                assignRoute.getInstance().reOrderRoutePoints();
            },
        });
    }



}
